using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Xml;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Entities.Modules;
using DotNetNuke.Services.Search;

using DesertedRoadStudios.BlogNetNuke.Common;

namespace DesertedRoadStudios.BlogNetNuke.Components
{
    public class BlogNetNukeController : ISearchable, IPortable, IUpgradeable
    {
        #region Public Methods

        // BNNDefault.aspx
        public BlogTab GetBlogTabInfo(int portalID, string tabPath)
        {
            return CBO.FillObject<BlogTab>(DataProvider.Instance().GetBlogTabInfo(portalID, -1, tabPath));
        }
        public BlogTab GetBlogTabInfo(int portalID, int moduleID)
        {
            return CBO.FillObject<BlogTab>(DataProvider.Instance().GetBlogTabInfo(portalID, moduleID, string.Empty));
        }
        public List<BlogTab> GetAllBlogTabInfo(int portalID)
        {
            return CBO.FillCollection<BlogTab>(DataProvider.Instance().GetAllBlogTabInfo(portalID));
        }

        // Module Page_Init
        public int UpdateTabID(int portalID, int moduleID, int tabID)
        {
            return DataProvider.Instance().UpdateTabID(portalID, moduleID, tabID);
        }

        // Module Host Settings
        public List<FriendlyURL> GetFriendlyURLs()
        {
            return CBO.FillCollection<FriendlyURL>(DataProvider.Instance().GetFriendlyURLs());
        }
        public void InsertFriendlyURL(string path)
        {
            DataProvider.Instance().InsertFriendlyURL(path);
        }
        public void DeleteFriendlyURL(int pathID)
        {
            DataProvider.Instance().DeleteFriendlyURL(pathID);
        }
        public string GetSetting(int portalID, int moduleID, string setting)
        {
            return DataProvider.Instance().GetSetting(portalID, moduleID, setting);
        }
        public Dictionary<string, string> GetSettings(int portalID, int moduleID)
        {
            Dictionary<string, string> settings = new Dictionary<string, string>();
            using (IDataReader reader = DataProvider.Instance().GetSettings(portalID, moduleID))
            {
                while (reader.Read())
                    settings.Add(reader["SettingName"].ToString(), reader["SettingValue"].ToString());
            }
            return settings;
        }
        public void SetSetting(int portalID, int moduleID, string setting, string value)
        {
            DataProvider.Instance().SetSetting(portalID, moduleID, setting, value);
        }
        public void ClearSettings(int portalID, int moduleID)
        {
            DataProvider.Instance().ClearSettings(portalID, moduleID);
        }

        // Posts
        public string GetTabPath(int portalID, int tabID, int moduleID)
        {
            return DataProvider.Instance().GetTabPath(portalID, tabID, moduleID);
        }
        public List<PostInfo> GetAllPosts(int portalID, int moduleID, int tabID)
        {
            return CBO.FillCollection<PostInfo>(DataProvider.Instance().GetAllPosts(portalID, moduleID, tabID));
        }
        public List<PostInfo> GetAllPublishedPosts(int portalID, int moduleID, int tabID)
        {
            return CBO.FillCollection<PostInfo>(DataProvider.Instance().GetAllPublishedPosts(portalID, moduleID, tabID));
        }
        public List<PostInfo> GetAllPostsUnderReview(int portalID, int moduleID, int tabID)
        {
            return CBO.FillCollection<PostInfo>(DataProvider.Instance().GetAllPostsUnderReview(portalID, moduleID, tabID));
        }
        public List<PostInfo> GetAllPostDrafts(int portalID, int moduleID, int tabID)
        {
            return CBO.FillCollection<PostInfo>(DataProvider.Instance().GetAllPostDrafts(portalID, moduleID, tabID));
        }
        public List<PostInfo> GetAllDeletedPosts(int portalID, int moduleID, int tabID)
        {
            return CBO.FillCollection<PostInfo>(DataProvider.Instance().GetAllDeletedPosts(portalID, moduleID, tabID));
        }
        public PostInfo GetPostByDateSlug(int portalID, int moduleID, DateTime publishedDate, string slug)
        {
            return CBO.FillObject<PostInfo>(DataProvider.Instance().GetPostByDateSlug(portalID, moduleID, publishedDate, slug));
        }
        public PostInfo GetPostByPostID(int portalID, int moduleID, Guid postID)
        {
            return CBO.FillObject<PostInfo>(DataProvider.Instance().GetPostByPostID(portalID, moduleID, postID));
        }
        public PostInfo GetPostByPostPath(int portalID, int moduleID, string postPath)
        {
            return CBO.FillObject<PostInfo>(DataProvider.Instance().GetPostByPostPath(portalID, moduleID, postPath));
        }
        public List<PostInfo> GetAllPostsByDate(int portalID, int moduleID, int tabID, DateTime publishedDate)
        {
            return CBO.FillCollection<PostInfo>(DataProvider.Instance().GetAllPostsByDate(portalID, moduleID, tabID, publishedDate));
        }
        public List<PostInfo> GetAllPostsByDateRange(int portalID, int moduleID, int tabID, DateTime beginDate, DateTime endDate)
        {
            return CBO.FillCollection<PostInfo>(DataProvider.Instance().GetAllPostsByDateRange(portalID, moduleID, tabID, beginDate, endDate));
        }
        public Guid ValidatePostTitle(int portalID, int moduleID, int tabID, string slug)
        {
            object postID =  DataProvider.Instance().ValidatePostTitle(portalID, moduleID, tabID, slug);
            if (postID == null)
                return Guid.Empty;
            else
                return (Guid)postID;
        }
        public void InsertPost(PostInfo post)
        {
            DataProvider.Instance().InsertPost(post);
        }
        public void UpdatePost(PostInfo post)
        {
            DataProvider.Instance().UpdatePost(post);
        }
        public void SetPostStatus(int portalID, int moduleID, Guid postID, PostStatus status)
        {
            DataProvider.Instance().SetPostStatus(portalID, moduleID, postID, status);
        }
        public List<PostInfo> GetAllPostsForCategory(int portalID, int moduleID, string slug)
        {
            return CBO.FillCollection<PostInfo>(DataProvider.Instance().GetAllPostsForCategory(portalID, moduleID, slug));
        }
        public List<PostInfo> GetAllPostsForTag(int portalID, int moduleID, string slug)
        {
            return CBO.FillCollection<PostInfo>(DataProvider.Instance().GetAllPostsForTag(portalID, moduleID, slug));
        }

        // Comments
        public List<CommentInfo> GetAllCommentsForPost(int portalID, int moduleID, Guid postID)
        {
            return CBO.FillCollection<CommentInfo>(DataProvider.Instance().GetAllCommentsForPost(portalID, moduleID, postID));
        }
        public void AddCommentToPost(CommentInfo comment)
        {
            DataProvider.Instance().AddCommentToPost(comment);
        }
        public void ApproveComment(Guid commentID, int portalID, int moduleID, Guid postID)
        {
            DataProvider.Instance().ApproveComment(commentID, portalID, moduleID, postID);
        }
        public void UnApproveComment(Guid commentID, int portalID, int moduleID, Guid postID)
        {
            DataProvider.Instance().UnApproveComment(commentID, portalID, moduleID, postID);
        }
        public void DeleteComment(Guid commentID, int portalID, int moduleID, Guid postID)
        {
            DataProvider.Instance().DeleteComment(commentID, portalID, moduleID, postID);
        }
        public void UnDeleteComment(Guid commentID, int portalID, int moduleID, Guid postID)
        {
            DataProvider.Instance().UnDeleteComment(commentID, portalID, moduleID, postID);
        }

        // Categories
        public List<CategoryInfo> GetAllCategories(int portalID, int moduleID)
        {
            return CBO.FillCollection<CategoryInfo>(DataProvider.Instance().GetAllCategories(portalID, moduleID));
        }
        public int AddCategory(CategoryInfo category)
        {
            return DataProvider.Instance().AddCategory(category);
        }
        public void UpdateCategory(CategoryInfo category)
        {
            DataProvider.Instance().UpdateCategory(category);
        }
        public void AddCategoryToPost(int categoryID, Guid postID)
        {
            DataProvider.Instance().AddCategoryToPost(categoryID, postID);
        }
        public List<int> GetAllCategoriesForPost(Guid postID)
        {
            List<int> categories = new List<int>();
            using (System.Data.IDataReader reader = DataProvider.Instance().GetAllCategoriesForPost(postID))
                while (reader.Read())
                    categories.Add(Convert.ToInt32(reader["CategoryID"]));
            return categories;
        }
        public List<PostsCategories> GetAllCategoriesForPosts(int portalID, int moduleID)
        {
            return CBO.FillCollection<PostsCategories>(DataProvider.Instance().GetAllCategoriesForPosts(portalID, moduleID));
        }
        public void DeleteAllCategoriesForPost(Guid postID)
        {
            DataProvider.Instance().DeleteAllCategoriesForPost(postID);
        }

        // Tags
        public int AddTag(TagInfo tag)
        {
            return DataProvider.Instance().AddTag(tag);
        }
        public void AddTagToPost(int tagID, Guid postID)
        {
            DataProvider.Instance().AddTagToPost(tagID, postID);
        }
        public int GetTagID(string tag, int portalID, int moduleID)
        {
            return DataProvider.Instance().GetTagID(tag, portalID, moduleID);
        }
        public List<TagInfo> GetAllTags(int portalID, int moduleID)
        {
            return CBO.FillCollection<TagInfo>(DataProvider.Instance().GetAllTags(portalID, moduleID));
        }
        public List<int> GetAllTagsForPost(Guid postID)
        {
            List<int> tags = new List<int>();
            using (System.Data.IDataReader reader = DataProvider.Instance().GetAllTagsForPost(postID))
                while (reader.Read())
                    tags.Add(Convert.ToInt32(reader["TagID"]));
            return tags;
        }
        public List<PostsTags> GetAllTagsForPosts(int portalID, int moduleID)
        {
            return CBO.FillCollection<PostsTags>(DataProvider.Instance().GetAllTagsForPosts(portalID, moduleID));
        }
        public void TagsForPost(Guid postID)
        {
            DataProvider.Instance().DeleteAllTagsForPost(postID);
        }
        public void DeleteAllTagsForPost(Guid postID)
        {
            DataProvider.Instance().DeleteAllTagsForPost(postID);
        }

        // TinyURLs
        public void AddTinyUrl(string domainName, int moduleID, bool logRedirects)
        {
            DataProvider.Instance().AddTinyUrl(domainName, moduleID, logRedirects);
        }

        public void AddTinyUrlRedirect(int tinyURLID, string code, Guid postID)
        {
            DataProvider.Instance().AddTinyUrlRedirect(tinyURLID, code, postID);
        }

        public void AddTinyUrlLog()
        {
            DataProvider.Instance().AddTinyUrlLog();
        }

        public void DeleteTinyUrlLog(int redirectID)
        {
            DataProvider.Instance().DeleteFriendlyURL(redirectID);
        }

        /*
        public IDataReader GetTinyUrlLog(int redirectID)
        {

        }*/

        public TinyURLInfo GetTinyUrl(Guid postID)
        {
            return CBO.FillObject<TinyURLInfo>(DataProvider.Instance().GetTinyUrl(postID));
        }

        public TinyURLInfo GetTinyUrlDomain(int moduleID)
        {
            return CBO.FillObject<TinyURLInfo>(DataProvider.Instance().GetTinyUrlDomain(moduleID));
        }

        public TinyURLInfo GetPostForTinyUrl(string domain, string code)
        {
            return CBO.FillObject<TinyURLInfo>(DataProvider.Instance().GetPostForTinyUrl(domain, code));
        }

        public List<string> GetTinyUrlDomains()
        {
            List<string> domainNames = new List<string>();
            using (System.Data.IDataReader reader = DataProvider.Instance().GetTinyUrlDomains())
                while (reader.Read())
                    domainNames.Add(reader["DomainName"].ToString());
            return domainNames;
        }
        
        #endregion

        #region ISearchable

        /// <summary>
        /// Implements the search interface required to allow DNN to index/search the content of your
        /// module
        /// </summary>
        /// <remarks>Remember you MUST implement this using your methods, this is for info only</remarks>
        /// <param name="modInfo"></param>
        /// <returns></returns>
        public DotNetNuke.Services.Search.SearchItemInfoCollection GetSearchItems(ModuleInfo modInfo)
        {
            SearchItemInfoCollection searchItems = new SearchItemInfoCollection();

        //    List<BlankModuleWithDalInfo> infos = GetBlankModuleWithDals(modInfo.ModuleID);

        //    foreach (BlankModuleWithDalInfo info in infos)
        //    {
        //        SearchItemInfo searchInfo = new SearchItemInfo(modInfo.ModuleTitle, info.Content, info.CreatedByUser, info.CreatedDate,
        //                                            modInfo.ModuleID, info.ItemId.ToString(), info.Content, "Item=" + info.ItemId.ToString());
        //        searchItems.Add(searchInfo);
        //    }

            return searchItems;
        }

        #endregion

        #region IPortable

        /// <summary>
        /// Exports a module to xml
        /// </summary>
        /// <remarks>You must implement this in a manner that matches your data...</remarks>
        /// <param name="ModuleID"></param>
        /// <returns></returns>
        public string ExportModule(int moduleID)
        {
            StringBuilder sb = new StringBuilder();

        //    List<BlankModuleWithDalInfo> infos = GetBlankModuleWithDals(moduleID);

        //    if (infos.Count > 0)
        //    {
        //        sb.Append("<BlankModuleWithDals>");
        //        foreach (BlankModuleWithDalInfo info in infos)
        //        {
        //            sb.Append("<BlogNetNuke>");
        //            sb.Append("<content>");
        //            sb.Append(XmlUtils.XMLEncode(info.Content));
        //            sb.Append("</content>");
        //            sb.Append("</BlogNetNuke>");
        //        }
        //        sb.Append("</BlankModuleWithDals>");
        //    }

            return sb.ToString();
        }

        /// <summary>
        /// imports a module from an xml file
        /// </summary>
        /// <remarks>You must implement this in a manner that matches your data...</remarks>
        /// <param name="ModuleID">The id that we are importing to</param>
        /// <param name="Content">Your exported XML content from the previous module</param>
        /// <param name="Version">The version of the module which it exported from</param>
        /// <param name="UserID">The user id of the user importing this data</param>
        public void ImportModule(int ModuleID, string Content, string Version, int UserID)
        {
            XmlNode infos = DotNetNuke.Common.Globals.GetContent(Content, "BlankModuleWithDals");

            foreach (XmlNode info in infos.SelectNodes("BlogNetNuke"))
            {
        //        BlankModuleWithDalInfo BlankModuleWithDalInfo = new BlankModuleWithDalInfo();
        //        BlankModuleWithDalInfo.ModuleId = ModuleID;
        //        BlankModuleWithDalInfo.Content = info.SelectSingleNode("content").InnerText;
        //        BlankModuleWithDalInfo.CreatedByUser = UserID;

        //        AddBlankModuleWithDal(BlankModuleWithDalInfo);
            }
        }

        #endregion

        #region IUpgradeable

        public string UpgradeModule(string Version)
        {
            switch (Version)
            {
                case "01.00.00":
                    {
                        

                        break;
                    }
            }

            return "True";
        }

        #endregion
    }
}
